package business.histocloud.algorithm.mds;

public class MDS {

    public static double[][] classical(double[][] p, int n) {
//        System.out.println("n="+n);
//        System.out.println("matrix input");
//        Matrix.print(p);
        double[][] p2 = Matrix.square(p);
//        System.out.println("matrix doubled");
//        Matrix.print(p2);
        
        double[][] In = Matrix.identity(n);
//        System.out.println("matrix I");
//        Matrix.print(In);
        
        double[][] m11 = Matrix.matrix11(n);
//        System.out.println("matrix 11");
//        Matrix.print(m11);
        
        double[][] p11 = Matrix.mutilply(1.0 / n, m11);
//        System.out.println("matrix p11");
//        Matrix.print(p11);
        
        double[][] mJ = Matrix.subtract(In, p11);
//        System.out.println("matrix mJ");
//        Matrix.print(mJ);
        
        double[][] mB = Matrix.mutilply(-0.5, mJ);
//        System.out.println("matrix mB");
//        Matrix.print(mB);
        
        mB = Matrix.multiply(mB, p2);
//        System.out.println("matrix mB x p2");
//        Matrix.print(mB);
        
        mB = Matrix.multiply(mB, mJ);
//        System.out.println("matrix mB x mJ");
//        Matrix.print(mB);

        Jama.Matrix A = new Jama.Matrix(mB);
        // compute the spectral decomposition
        Jama.EigenvalueDecomposition e = A.eig();
        Jama.Matrix V = e.getV();
        double[] eigenvalues = e.getRealEigenvalues();
        double[][] eigenVectors = V.getArray();
        
        System.out.println("eigen value:");
        for (int i = 0; i < eigenvalues.length; i++) {
            System.out.println(eigenvalues[i] + ";");
        }
        double[] eigen2values = Matrix.extractVector(eigenvalues, 2);
//        System.out.println("Eigen values:");
        double[][] eigen2vectors = new double[eigen2values.length][V.getRowDimension()];
        for (int i = 0; i < eigen2values.length; i++) {
//            System.out.println(eigen2values[i] + ";");
            for (int j = 0; j < eigenvalues.length; j++) {
                if (eigen2values[i] == eigenvalues[j]) {
                    eigen2vectors[i] = Matrix.getColumn(eigenVectors, j);
                }
            }
        }
        
        double[][] digonal = Matrix.squaredDigonalMatrix(eigen2values, 2);
//        System.out.println("diagonal");
//        Matrix.print(digonal);
        
        eigen2vectors = Matrix.transpose(eigen2vectors);
//        System.out.println("eigen2vector");
//        Matrix.print(eigen2vectors);
        
        mB = Matrix.multiply(eigen2vectors, digonal);
//        System.out.println("matrix b a retourner:");
//        Matrix.print(mB);
        mB = Matrix.transpose(mB);
        return mB;
    }
}
